package com.exchange.plugin.webSocket;

import org.tio.core.Tio;
import org.tio.core.ChannelContext;
import org.tio.http.common.HttpRequest;
import org.tio.http.common.HttpResponse;
import org.tio.websocket.common.WsRequest;
import org.tio.websocket.common.WsResponse;
import org.tio.websocket.server.handler.IWsMsgHandler;
import com.exchange.constant.BizConst;
import com.jfinal.kit.Kv;
import com.jfinal.kit.PropKit;
import com.jfinal.plugin.redis.Cache;
import com.jfinal.plugin.redis.Redis;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;

public class MyWsMsgHandler extends BaseWebSocket implements IWsMsgHandler {

//	@Inject
	
	
	public static final MyWsMsgHandler me = new MyWsMsgHandler();
	
	private MyWsMsgHandler() {

	}

	/**
	 * 握手时走这个方法，业务可以在这里获取cookie，request参数等,有的绑没得就不绑
	 * ws://192.168.0.192:9326?token=1234567
	 */
	@Override
	public HttpResponse handshake(HttpRequest request, HttpResponse httpResponse, ChannelContext channelContext) {
		String token = request.getParam("token");//获取token
		if(StrUtil.isNotEmpty(token)) {
			Cache redis = Redis.use(PropKit.get("redisName"));//将用户id绑定
			if(redis.exists(token)) {
				Tio.bindUser(channelContext, redis.get(token));
			}
		}
		return httpResponse;
	}

	/** 
	 * 客户端连上后,服务器首次发消息
	 */
	@Override
	public void onAfterHandshaked(HttpRequest httpRequest, HttpResponse httpResponse, ChannelContext channelContext) {
		sendQuotation(channelContext);//行情
		sendEntrust(channelContext);//委托
	}

	/**
	 * 字节消息（binaryType = arraybuffer）过来后会走这个方法
	 */
	@Override
	public Object onBytes(WsRequest wsRequest, byte[] bytes, ChannelContext channelContext) {
		return null;
	}

	/**
	 * 当客户端发close flag时，会走这个方法
	 */
	@Override
	public Object onClose(WsRequest wsRequest, byte[] bytes, ChannelContext channelContext) {
		Tio.unbindGroup(channelContext);
		Tio.remove(channelContext, "receive close flag");
		return null;
	}

	/*
	 * 字符消息（binaryType = blob）过来后会走这个方法
	 * text : { "token":xxx,"coin":xxx,"market":xxx,"tickTime":xxx,"type":xxx,"from":xxx,"to":xxx, "text":xxx}
	 * 订阅,取消订阅,聊天,请求
	 */
	@Override
	public Object onText(WsRequest wsRequest, String text, ChannelContext channelContext) {
//		WsSessionContext wsSessionContext = (WsSessionContext) channelContext.get();
//		HttpRequest httpRequest = wsSessionContext.getHandshakeRequest();//获取websocket握手包
		if(!JSONUtil.isJsonObj(text)) {
			return null;
		}
		JSONObject jo = JSONUtil.parseObj(text);
		int type = jo.getInt("type");
		if		(type == BizConst.socket.TOPIC_KLINE) {
			Tio.bindGroup(channelContext, BizConst.socket.TOPIC_KLINE + jo.getStr("coin") + jo.getStr("market") + jo.getStr("tickTime"));
			return null;
		}else if(type == BizConst.socket.TOPIC_HANDICAP) {
			Kv obj = getHandicap(jo.getStr("coin") + jo.getStr("market"));
			obj.set("type", BizConst.socket.HANDICAP);
			Tio.bindGroup(channelContext, BizConst.socket.TOPIC_HANDICAP + jo.getStr("coin") + jo.getStr("market"));
			return WsResponse.fromBytes(obj.toJson().getBytes());
		}else if(type == BizConst.socket.UN_TOPIC_KLINE) {
			Tio.unbindGroup(BizConst.socket.TOPIC_KLINE + jo.getStr("coin") + jo.getStr("market") + jo.getStr("tickTime"), channelContext);
			return null;
		}else if(type == BizConst.socket.UN_TOPIC_HANDICAP) {
			Tio.unbindGroup(BizConst.socket.TOPIC_HANDICAP + jo.getStr("coin") + jo.getStr("market"), channelContext);
			return null;
		}else if(type == BizConst.socket.PANT) {
			return null;
		}else if(type == BizConst.socket.REQ_KLINE_HISTORY) {
			Kv obj = getKLineH(jo.getStr("coin") + jo.getStr("market"), jo.getStr("tickTime"), jo.getLong("from"), jo.getLong("to"));
			obj.set("type", BizConst.socket.KLINE_HISTORY);
			return WsResponse.fromBytes(obj.toJson().getBytes());
		}else if(type == BizConst.socket.BUSTYPE_TEXT) {
			
//			String msg = jo.put("fromUserId", Integer.parseInt(channelContext.userid)).put("toUserId", null).toString();
//			WsResponse wsResponse = WsResponse.fromText(msg, ServerConfig.CHARSET);
//			Tio.sendToUser(channelContext.tioConfig, jo.getInt("toUserId").toString(), wsResponse);
			return null;
		}else {
			return null;
		}
	}
	
	
	
	
	/**
	 * 行情发送只要发生了交易就调用这个方法，将行情传出去)（还需要把行情存在redis中，用于用户首次请求）
	 * 获取所有币种的最新行情,市场交易行情订阅（最高价，最低价，交易数量，涨跌情况。。。很多地方需要展示）
	 */
	public void subQuotation(Kv obj) {
		obj.set("type", BizConst.socket.HNAG_QING);
    	WsResponse wsResponse = WsResponse.fromBytes(obj.toJson().getBytes());
    	Tio.sendToAll(WebsocketStarter.serverTioConfig, wsResponse);
	}
	
	/**
	 * 发送k线变化,ok
	 */
	public void sendKLine(String coinPairTick,String tickTime, Kv obj) {
		obj.set("type", BizConst.socket.KLINE);
		WsResponse wsResponse = WsResponse.fromBytes(obj.toJson().getBytes());
		Tio.sendToGroup(WebsocketStarter.serverTioConfig, BizConst.socket.TOPIC_KLINE + coinPairTick + tickTime, wsResponse);
	}
	
	/**
	 * 买卖盘盘口
	 */
	public void subHandicap(String coinPair,Kv obj) {
		obj.set("type", BizConst.socket.HANDICAP);
		WsResponse wsResponse = WsResponse.fromBytes(obj.toJson().getBytes());
		Tio.sendToGroup(WebsocketStarter.serverTioConfig, BizConst.socket.TOPIC_HANDICAP + coinPair, wsResponse);
	}
	
	/**
	 * 根据account，如委托
	 */
	public void sendEntrust(String account,Kv obj) {
		obj.set("type", BizConst.socket.ENTRUST);
		WsResponse wsResponse = WsResponse.fromBytes(obj.toJson().getBytes());
		Tio.sendToUser(WebsocketStarter.serverTioConfig, account, wsResponse);
	}
	
	
	/**
	 * 发送k线历史
	 */
//	public void sendKLineH(String coinPair,Long from,Long to,ChannelContext channelContext) {
//		Kv obj = getKLineH(coinPair, from, to);
//		obj.set("type", value);
//		WsResponse wsResponse = WsResponse.fromBytes(obj.toJson().getBytes());
//		Tio.send(channelContext, wsResponse);
//	}
	
	/**
	 * 盘口信息订阅之后直接发送的
	 */
//	public void sendHandicap(String coinPair, ChannelContext channelContext) {
//		Kv obj = getHandicap(coinPair);
//		obj.set("type", value);
//		WsResponse wsResponse = WsResponse.fromBytes(obj.toJson().getBytes());
//		Tio.send(channelContext, wsResponse);
//	}
	
	/**
	 * 行情通知,订阅之后直接发送的
	 */
	public void sendQuotation(ChannelContext channelContext) {
		Kv obj = getQuotation();
		obj.set("type", BizConst.socket.HNAG_QING);
		WsResponse wsResponse = WsResponse.fromBytes(obj.toJson().getBytes());
		Tio.send(channelContext, wsResponse);
	}
	
	 /**
	  * 我的委托,订阅之后直接发送的
	  */
	 public void sendEntrust(ChannelContext channelContext) {
		 Kv obj = getEntrust(channelContext.userid);
		 obj.set("type", BizConst.socket.ENTRUST);
		 WsResponse wsResponse = WsResponse.fromBytes(obj.toJson().getBytes());
		 Tio.send(channelContext, wsResponse);
	 }
 
	
	

}
